package com.ning;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/*
@李子宁
Happy,happy everyday!
冲鸭！
2021/3/25

*/
public class TencentDemo {
    private final static Charset UTF8 = StandardCharsets.UTF_8;
    /* private final static String SECRET_ID = "AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE";
     private final static String SECRET_KEY = "Gu5t9xGARNpq86cd98joQYCN3EXAMPLE";*/
    private final static String SECRET_ID = "2713c6d9257e6547f9c3c26457132b41";
    private final static String SECRET_KEY = "cb42fe18c3e54b3f9e73415d6d92a715";
    private final static String CT_JSON = "application/json; charset=utf-8";

    public static byte[] hmac256(byte[] key, String msg) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
        mac.init(secretKeySpec);
        return mac.doFinal(msg.getBytes(UTF8));
    }

    public static String sha256Hex(String s) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] d = md.digest(s.getBytes(UTF8));
        return DatatypeConverter.printHexBinary(d).toLowerCase();

    }

    public static void main(String[] args) throws Exception {
        String service = "industry";
        String host = "yunxiaowei.qcloud.com";
        String action = "GetSynonymEntityList";
        String version = "v1";
        String algorithm = "HMAC-SHA256";
        //String timestamp = "1551113065";
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 注意时区，否则容易出错
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
       // System.out.println(date);

        // ************* 步骤 1：拼接规范请求串 *************
        String httpRequestMethod = "POST";
        String canonicalUri = "/industry-cgi";
        String canonicalQueryString = "";
        String canonicalHeaders = "content-type:application/json;charset=utf-8\n";
        String signedHeaders = "content-type";
        Map<String,Object> map = new HashMap<>();

       // map.put("feature_id","2_WenDaGuanLi");

        map.put("product_id","2a_1616729140571_79");
        map.put("dict_category","synonym");
        List<String> list = new ArrayList<>();
        map.put("dict_id","1377155806794694656");

        String payload = map.toString();
        System.out.println();
        String hashedRequestPayload = sha256Hex(payload);
        String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
                + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
   //     System.out.println("canonicalRequest: "+canonicalRequest );

        // ************* 步骤 2：拼接待签名字符串 *************
        String credentialScope = date + "/" + service + "/" + "yxw_request";
        String hashedCanonicalRequest = sha256Hex(canonicalRequest);
        String stringToSign = algorithm + "\n" + timestamp  + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
      //  System.out.println("stringToSign: " + stringToSign);

        // ************* 步骤 3：计算签名 *************
        byte[] secretDate = hmac256(("YXW" + SECRET_KEY).getBytes(UTF8), date);
        byte[] secretService = hmac256(secretDate, service);
        byte[] secretSigning = hmac256(secretService, "yxw_request");
        String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
        System.out.println();
        System.out.println();
        System.out.println();


        // ************* 步骤 4：拼接 Authorization *************
        String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "
                + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
       // System.out.println(authorization);
        System.out.println("*********************************");
        StringBuffer buffer = sendTencentPostData("https://industry.sparta.html5.qq.com/industry-cgi", action, SECRET_ID, SECRET_KEY, map);

    }
//1380365038943518720词典
    public static StringBuffer sendTencentPostData(String urlstr,String method,String secretId,String secretKey,Map<String,Object> params){
        URL connect;
        StringBuffer data = new StringBuffer();
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000L);
        try{
            connect = new URL(urlstr);
            HttpURLConnection connection = (HttpURLConnection) connect.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("content-type","application/json; charset=utf-8");
            connection.setRequestProperty("YXW-Action",method);

            connection.setRequestProperty("YXW-Timestamp",timestamp);
            connection.setRequestProperty("YXW-Version","v1");
            connection.setRequestProperty("YXW-SecretId",secretId);

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            format.setTimeZone(TimeZone.getTimeZone("UTC"));
            String paramsStr = JSON.toJSONString(params);

            // ************* 步骤 1：拼接规范请求串 *************
            String httpRequestMethod = "POST";
            String canonicalUri = "/industry-cgi";
            String canonicalQueryString = "";
            String canonicalHeaders = "content-type:application/json; charset=utf-8\n";
            String signedHeaders = "content-type";
            String hashedRequestPayload = sha256Hex(paramsStr);
            String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
                    + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
            // ************* 步骤 2：拼接待签名字符串 *************
            String date = format.format(new Date());
            String service = "industry";
            String algorithm = "HMAC-SHA256";
            String credentialScope = date + "/" + service + "/" + "yxw_request";
            String hashedCanonicalRequest = sha256Hex(canonicalRequest);
            String stringToSign = algorithm + "\n" + timestamp  + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
            // ************* 步骤 3：计算签名 *************
            byte[] secretDate = hmac256(("YXW" + secretKey).getBytes(UTF8), date);
            byte[] secretService = hmac256(secretDate, service);
            byte[] secretSigning = hmac256(secretService, "yxw_request");
            String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();

            String authorization = algorithm + " " + "Credential=" + secretId + "/" + credentialScope + ", SignedHeaders=" + signedHeaders
                    + ", Signature=" + signature;
            connection.setRequestProperty("Authorization",authorization);

            OutputStreamWriter paramout = new OutputStreamWriter(connection.getOutputStream(),"UTF-8");
            System.out.println(new Timestamp(System.currentTimeMillis()));
            System.out.println("data: " + JSON.toJSONString(params));
            System.out.println("timestamp: "+ timestamp);

            System.out.println("signature: " + signature);
            System.out.println(authorization);
            paramout.write(paramsStr);
            paramout.flush();
            System.out.println(params);

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
            String line;
            while ((line = reader.readLine()) != null){
                data.append(line);
            }

            reader.close();
            paramout.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String,Object> parse = (Map<String, Object>) JSONObject.parse(data.toString());
        System.out.println("parse: " + parse);
        Integer code = (Integer) parse.get("code");
        System.out.println(code == 0);
        return data;
    }
}
